#include "drv_api.h"
#include "usw/include/drv_common.h"
#include "ctc_cli.h"
#include "ctc_dkit.h"
#include "ctc_usw_dkit.h"
#include "ctc_usw_dkit_monitor.h"
#include "ctc_dkit_common.h"

#define CTC_DKIT_MONITOR_CONGEST_LEVEL_NUM  3
#define CTC_DKIT_MONITOR_TC_NUM  8

#define CTC_DKIT_MONITOR_NETWORK_CHANNEL_QUEUE_BASE  0
#define CTC_DKIT_MONITOR_MISC_CHANNEL_QUEUE_BASE  512
#define CTC_DKIT_MONITOR_EXCP_QUEUE_BASE  640
#define CTC_DKIT_MONITOR_NETWORK_MISC_QUEUE_BASE  768
#define CTC_DKIT_MONITOR_EXTENDER_QUEUE_BASE  1024
#define CTC_DKIT_MONITOR_MAX_QUEUE_NUM    ((DRV_FROM_TMM(lchip)) ? 12288 : (DRV_IS_DUET2(lchip)?1280:4096))

#define CTC_DKIT_MONITOR_DMA_CHANNEL_ID_BASE 79
#define CTC_DKIT_MONITOR_NETWORK_CHANNEL_NUM 64
#define CTC_DKIT_MONITOR_NETWORK_CHANNEL_NUM_PER_DP (DRV_IS_TMG(lchip) ? 52 : 112)
#define CTC_DKIT_MONITOR_CHAN_NUM_PER_DP (DRV_IS_TMG(lchip) ? 64 : 128)
#define CTC_DKIT_MONITOR_SC_NUM 4
#define CTC_DKIT_MONITOR_QUEUE_ENTRY_MEM_PRE_RAM (26*1024)
#define CTC_DKIT_MONITOR_UC_QUEUE_ENTRY_MEM_PRE_RAM 128
#define CTC_DKIT_MONITOR_MC_QUEUE_ENTRY_MEM_PRE_RAM 96

#define CTC_DKITS_SENSOR_MAX_VOL_CNT  7

extern ctc_dkit_chip_api_t* g_dkit_chip_api[CTC_DKITS_MAX_LOCAL_CHIP_NUM];
extern ctc_dkit_master_t* g_usw_dkit_master[CTC_DKITS_MAX_LOCAL_CHIP_NUM];
extern bool dal_chip_is_sim(uint8 ldev);
STATIC uint8
_ctc_usw_dkit_monitor_get_congest_level(uint8 lchip, bool is_igress, uint8 sc)
{
    uint8 i = 0;
    uint32 total = 0;
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 tbl_id = MaxTblId_t;
    uint32 field_id = 0;

    if (is_igress)
    {
        cmd = DRV_IOR(DsIrmScCnt_t, DsIrmScCnt_g_0_scCnt_f );
        DRV_FIELD_IOCTL(lchip, 0, cmd, &total);
        tbl_id = DsIrmScCngThrdProfile_t;
        field_id = DsIrmScCngThrdProfile_g_0_scCngThrd_f;
    }
    else
    {
        cmd = DRV_IOR(DsErmScCnt_t, DsErmScCnt_g_0_scCnt_f + sc);
        DRV_FIELD_IOCTL(lchip, 0, cmd, &total);
        tbl_id = DsErmScCngThrdProfile_t;
        field_id = DsErmScCngThrdProfile_g_0_scCngThrd_f;
    }

    for (i = 0; i < CTC_DKIT_MONITOR_CONGEST_LEVEL_NUM; i++)
    {
        cmd = DRV_IOR(tbl_id, field_id + i);
        DRV_FIELD_IOCTL(lchip, sc, cmd, &value);
        if ((total>>5) < value)
        {
            return i;
        }
    }

    return i;
}

STATIC uint32
_ctc_usw_dkit_monitor_get_channel_by_gport(uint8 lchip, uint16 gport)
{
    uint16 local_phy_port = 0;
    uint32 channel = 0xFFFFFFFF;
    uint8 i = 0;
    uint32 cmd = 0;
    uint32 value = 0;

    local_phy_port = gport;
    for (i = 0; i < CTC_DKIT_ONE_SLICE_CHANNEL_NUM; i++)
    {
        cmd = DRV_IOR(IpeHeaderAdjustPhyPortMap_t, IpeHeaderAdjustPhyPortMap_localPhyPort_f);
        DRV_FIELD_IOCTL(lchip, CTC_DKITS_CHANNEL_ENCODE(i), cmd, &value);
        if (value == local_phy_port)
        {
            channel = i;
            break;
        }
    }

    return channel;
}

STATIC uint32
_ctc_usw_dkit_monitor_get_channel_by_queue_id(uint8 lchip, uint16 queue_id)
{
    uint32 field_val = 0;
    uint32 cmd = 0;
    uint16 group_id = 0;
    uint8 channel = 0;
    uint8 cpu_queue_mode = 0;
    uint8 subquenum = 0;

    if (queue_id < CTC_DKIT_MONITOR_MISC_CHANNEL_QUEUE_BASE)
    {
        channel = queue_id / 8;
    }
    else if(queue_id < CTC_DKIT_MONITOR_EXCP_QUEUE_BASE)
    {
        channel = queue_id / 8;
    }
    else if(queue_id < CTC_DKIT_MONITOR_NETWORK_MISC_QUEUE_BASE)
    {
        cmd = DRV_IOR(QWriteCtl_t, QWriteCtl_cpuQueueMode_f);
        DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val);
        cpu_queue_mode = field_val;

        if (cpu_queue_mode == 1)
        {
            channel = CTC_DKIT_MONITOR_DMA_CHANNEL_ID_BASE + (queue_id - CTC_DKIT_MONITOR_EXCP_QUEUE_BASE) / 32;
        }
        else
        {
            channel = CTC_DKIT_MONITOR_DMA_CHANNEL_ID_BASE + (queue_id - CTC_DKIT_MONITOR_EXCP_QUEUE_BASE) / 64;
        }
    }
    else if(queue_id < CTC_DKIT_MONITOR_EXTENDER_QUEUE_BASE)
    {
        channel = (queue_id - CTC_DKIT_MONITOR_NETWORK_MISC_QUEUE_BASE) / 4;
    }
    else if(queue_id < CTC_DKIT_MONITOR_MAX_QUEUE_NUM)
    {
        subquenum = DRV_IS_DUET2(lchip) ? 4:8;
        group_id = (queue_id - CTC_DKIT_MONITOR_EXTENDER_QUEUE_BASE) / subquenum;
        cmd = DRV_IOR(DsQMgrGrpChanMap_t, DsQMgrGrpChanMap_channelId_f);
        DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val);
        channel = field_val;
    }
    else
    {
        CTC_DKIT_PRINT("Invalid queue_id:%d!!!\n", queue_id);
    }

    return channel;
}

int32
ctc_usw_dkit_monitor_show_queue_id(void* p_para)
{
    uint32 cmd = 0;
    uint32 qid = 0;
    uint32 chanid = 0;
    uint32 chanid_per_dp = 0;
    uint8 i = 0;
    uint32 tbl_idx = 0;
    uint32 local_phy_port = 0;
    uint16 gport  = 0;
    uint8 gchip = 0;
    uint8 lchip = 0;
    ctc_dkit_monitor_para_t* p_monitor_para = (ctc_dkit_monitor_para_t*)p_para;

    DKITS_PTR_VALID_CHECK(p_para);
    lchip = p_monitor_para->lchip;
    CTC_DKIT_LCHIP_CHECK(lchip);
    DRV_INIT_CHECK(lchip);
    if (DRV_FROM_AT(lchip))
    {
        g_dkit_chip_api[lchip]->dkits_show_q_id(lchip);
        return CLI_SUCCESS;
    }
    CTC_DKIT_GET_GCHIP(lchip, gchip);
    CTC_DKIT_PRINT("%-6s %-10s %-10s %-10s\n", "NO.", "QueID", "ChanId","Port");
    CTC_DKIT_PRINT("-----------------------------------\n");
    for (i = 0; i < 5; i++)
    {
        if (DRV_FROM_TMM(lchip))
        {
            cmd = DRV_IOR(QMgrQWriteDebugInfo_t, QMgrQWriteDebugInfo_queueIdMon0_f + i);
        }
        else
        {
            cmd = DRV_IOR(QMgrEnqDebugInfo_t, QMgrEnqDebugInfo_queueIdMon0_f + i);
        }
        DRV_FIELD_IOCTL(lchip, 0, cmd, &qid);

        if (g_dkit_chip_api[lchip]->dkits_get_channel_by_queue)
        {
            chanid = g_dkit_chip_api[lchip]->dkits_get_channel_by_queue(lchip, qid);
            chanid_per_dp = chanid < CTC_DKIT_MONITOR_CHAN_NUM_PER_DP ? chanid : (chanid % CTC_DKIT_MONITOR_CHAN_NUM_PER_DP);
        }
        else
        {
            chanid = _ctc_usw_dkit_monitor_get_channel_by_queue_id(lchip, qid);
        }


        if (chanid < CTC_DKIT_MONITOR_NETWORK_CHANNEL_NUM || (DRV_FROM_TMM(lchip) && chanid_per_dp < CTC_DKIT_MONITOR_NETWORK_CHANNEL_NUM_PER_DP))
        {
            cmd = DRV_IOR(IpeHeaderAdjustPhyPortMap_t, IpeHeaderAdjustPhyPortMap_localPhyPort_f);
            tbl_idx = CTC_DKITS_CHANNEL_ENCODE(chanid);
            DRV_FIELD_IOCTL(lchip, tbl_idx, cmd, &local_phy_port);
            gport = CTC_DKIT_DRV_LPORT_TO_CTC_GPORT(gchip, local_phy_port);
            CTC_DKIT_PRINT("%-6d %-10d %-10d 0x%04x\n", i + 1, qid, chanid, gport);
        }
        else
        {
            CTC_DKIT_PRINT("%-6d %-10d %-10d %-6s\n", i + 1, qid, chanid, "-");
        }

    }

    CTC_DKIT_PRINT("-----------------------------------\n");
    CTC_DKIT_PRINT("Tips: NO.1 is the newest QueueID\n\n");

    return CLI_SUCCESS;
}

STATIC int32
_ctc_usw_dkit_monitor_q_depth_igr_summary(uint8 lchip, sal_file_t p_wf)
{
    uint32 cmd = 0;
    uint8 i = 0;
    uint32 value0 = 0;
    char desc[16] = {0};
    uint8 congest_level = 0;
    uint32 c2c_packet_cnt = 0;
    uint32 critical_packet_cnt = 0;
    uint32 igr_total_cnt = 0;
    uint32 c2c_packet_thrd = 0;
    uint32 critical_packet_thrd = 0;
    uint32 igr_total_thrd = 0;
    uint32 sc_packet_cnt = 0;
    uint32 sc_packet_thrd = 0;
    DsIrmMiscCnt_m irm_misc_cnt;
    DsIrmMiscThrd_m irm_misc_thrd;

    sal_memset(&irm_misc_cnt, 0, sizeof(DsIrmMiscCnt_m));
    cmd = DRV_IOR(DsIrmMiscCnt_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &irm_misc_cnt);
    GetDsIrmMiscCnt(A, c2cCnt_f, &irm_misc_cnt, &c2c_packet_cnt);
    GetDsIrmMiscCnt(A, criticalCnt_f, &irm_misc_cnt, &critical_packet_cnt);
    GetDsIrmMiscCnt(A, totalCnt_f, &irm_misc_cnt, &igr_total_cnt);

    sal_memset(&irm_misc_thrd, 0, sizeof(DsIrmMiscThrd_m));
    cmd = DRV_IOR(DsIrmMiscThrd_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &irm_misc_thrd);
    GetDsIrmMiscThrd(A, c2cThrd_f, &irm_misc_thrd, &c2c_packet_thrd);
    GetDsIrmMiscThrd(A, criticalThrd_f, &irm_misc_thrd, &critical_packet_thrd);
    GetDsIrmMiscThrd(A, totalThrd_f, &irm_misc_thrd, &igr_total_thrd);
    if DRV_FROM_TMM(lchip)
    {
        CTC_DKITS_PRINT_FILE(p_wf, "\n-----------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10s %-10s\n", "Type", "Depth", "Thrd");
        CTC_DKITS_PRINT_FILE(p_wf, "-----------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", "Total", igr_total_cnt, igr_total_thrd);
        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", "Critical", critical_packet_cnt, critical_packet_thrd);
        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", "C2C", c2c_packet_cnt, c2c_packet_thrd);

        for (i = 0; i < CTC_DKIT_MONITOR_SC_NUM; i++)
        {
            cmd = DRV_IOR(DsIrmScThrd_t, DsIrmScThrd_scThrd_f);
            DRV_FIELD_IOCTL(lchip, i, cmd, &sc_packet_thrd);
            cmd = DRV_IOR(DsIrmScCnt_t, DsIrmScCnt_g_0_scCnt_f + i);
            DRV_FIELD_IOCTL(lchip, 0, cmd, &sc_packet_cnt);
            sal_sprintf(desc, "%s%d", "SC", i);
            CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", desc, sc_packet_cnt, sc_packet_thrd);
        }
    }
    else
    {
        congest_level = _ctc_usw_dkit_monitor_get_congest_level(lchip, TRUE, 0);
        CTC_DKITS_PRINT_FILE(p_wf, "\n----------congest config-----------\n");
        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10s\n", "level", "Thrd");
        CTC_DKITS_PRINT_FILE(p_wf, "-----------------------------------\n");
        for (i = 0; i < CTC_DKIT_MONITOR_CONGEST_LEVEL_NUM; i++)
        {
            cmd = DRV_IOR(DsIrmScCngThrdProfile_t, DsIrmScCngThrdProfile_g_0_scCngThrd_f + i);
            DRV_FIELD_IOCTL(lchip, 0, cmd, &value0);
            if (i == congest_level)
            {
                sal_sprintf(desc, "%d%s", i, " (*)");
            }
            else
            {
                sal_sprintf(desc, "%d", i);
            }
            CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d\n", desc, value0 << 5);
        }

        CTC_DKITS_PRINT_FILE(p_wf, "\n-----------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10s %-10s\n", "Type", "Depth", "Thrd");
        CTC_DKITS_PRINT_FILE(p_wf, "-----------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", "Total", igr_total_cnt, igr_total_thrd);

        if ((igr_total_cnt >= (critical_packet_cnt + c2c_packet_cnt))
            && (igr_total_thrd >= (critical_packet_thrd + c2c_packet_thrd)))
        {
            CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", "Normal",
                                 (igr_total_cnt - critical_packet_cnt - c2c_packet_cnt),
                                 igr_total_thrd - critical_packet_thrd - c2c_packet_thrd);
        }

        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", "Critical", critical_packet_cnt, critical_packet_thrd);
        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", "C2C", c2c_packet_cnt, c2c_packet_thrd);
    }

    return CLI_SUCCESS;
}

STATIC int32
_ctc_usw_dkit_monitor_q_depth_igr_detail_port_tc(uint8 lchip, uint16 channel, sal_file_t p_wf)
{
    uint8 i = 0;
    char desc[16] = {0};
    uint32 depth = 0 ;
    uint32 index= 0;
    uint32 cmd = 0;
    uint8 congest_level = 0;
    uint32 profId = 0;
    uint32 port_tc_thrd = 0;

    congest_level = DRV_FROM_TMM(lchip) ?  0 : (_ctc_usw_dkit_monitor_get_congest_level(lchip, TRUE, 0));
    CTC_DKITS_PRINT_FILE(p_wf, "\n--------------------------------------\n");
    CTC_DKITS_PRINT_FILE(p_wf, "%-10s%-10s%-10s\n", "TC",  "Depth", "Thrd");
    CTC_DKITS_PRINT_FILE(p_wf, "--------------------------------------\n");
    index = channel;
    for (i = 0; i < CTC_DKIT_MONITOR_TC_NUM; i++)
    {
        cmd = DRV_IOR(DsIrmPortTcCnt_t, (DRV_FROM_TMM(lchip) ? DsIrmPortTcCnt_portTcCnt_f : DsIrmPortTcCnt_u_g1_portTcCnt_f));
        DRV_FIELD_IOCTL(lchip, (((index & 0x3f) << 3) + i), cmd, &depth);

        cmd = DRV_IOR(DsIrmPortTcCfg_t, DsIrmPortTcCfg_u_g1_portTcLimitedThrdProfId_f);
        DRV_FIELD_IOCTL(lchip, (((index & 0x3f) << 3) + i), cmd, &profId);

        cmd = DRV_IOR(DsIrmPortTcLimitedThrdProfile_t, DsIrmPortTcLimitedThrdProfile_g_0_portTcLimitedThrd_f);
        DRV_FROM_TMM(lchip) ? (DRV_FIELD_IOCTL(lchip, (((index & 0x3f) << 3) + i), cmd, &port_tc_thrd)) : (DRV_FIELD_IOCTL(lchip, (((profId&0xF) << 2) + congest_level), cmd, &port_tc_thrd));

        sal_sprintf(desc, "TC%d", i);
        CTC_DKITS_PRINT_FILE(p_wf, "%-10s%-10d%-10d\n", desc,  depth, port_tc_thrd << 3);
    }

    return CLI_SUCCESS;
}

STATIC int32
_ctc_usw_dkit_monitor_q_depth_igr_detail(uint8 lchip, uint16 gport, sal_file_t p_wf)
{
    uint32 cmd = 0;
    uint32 channel = 0;
    uint32 index = 0;
    uint32 depth = 0;
    uint32 local_phy_port = 0;
    uint32 gchip = 0;
    uint32 i = 0;
    uint8 congest_level = 0;
    uint32 profId = 0;
    uint32 port_thrd = 0;
    bool b_all_zero = TRUE;

    congest_level = DRV_FROM_TMM(lchip) ?  0 : (_ctc_usw_dkit_monitor_get_congest_level(lchip, TRUE, 0));
    if (0xFFFF == gport)
    {
        CTC_DKITS_PRINT_FILE(p_wf, "\n--------------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_wf, "%-10s%-10s%-10s%-10s\n",
                       "Port", "Channel", "Depth", "Thrd");
        CTC_DKITS_PRINT_FILE(p_wf, "--------------------------------------\n");
        for (i = 0; i < CTC_DKIT_ONE_SLICE_CHANNEL_NUM; i++)
        {
            cmd = DRV_IOR(DsIrmPortCnt_t, DsIrmPortCnt_portCnt_f);
            DRV_FIELD_IOCTL(lchip, i, cmd, &depth);
            if (depth)
            {
                cmd = DRV_IOR(IpeHeaderAdjustPhyPortMap_t, IpeHeaderAdjustPhyPortMap_localPhyPort_f);
                DRV_FIELD_IOCTL(lchip, CTC_DKITS_CHANNEL_ENCODE(i), cmd, &local_phy_port);
                CTC_DKIT_GET_GCHIP(lchip, gchip);

                cmd = DRV_IOR(DsIrmPortCfg_t, DsIrmPortCfg_portLimitedThrdProfId_f);
                DRV_FIELD_IOCTL(lchip, i, cmd, &profId);

                cmd = DRV_IOR(DsIrmPortLimitedThrdProfile_t, DsIrmPortLimitedThrdProfile_g_0_portLimitedThrd_f);
                DRV_FROM_TMM(lchip) ?  (DRV_FIELD_IOCTL(lchip, i, cmd, &port_thrd)) : (DRV_FIELD_IOCTL(lchip, (((profId&0xf) << 2) + congest_level), cmd, &port_thrd)) ;

                CTC_DKITS_PRINT_FILE(p_wf, "0x%04x    %-10d%-10d%-10d\n",
                                     CTC_DKIT_DRV_LPORT_TO_CTC_GPORT(gchip, local_phy_port),
                                     i, depth, (port_thrd << 3));
                b_all_zero = FALSE;
            }

        }
        if (b_all_zero)
        {
            CTC_DKITS_PRINT_FILE(p_wf, "All port depth is zero!!!\n");
        }
        CTC_DKITS_PRINT_FILE(p_wf, "--------------------------------------\n");
    }
    else
    {
        channel = ((g_dkit_chip_api[lchip]->dkits_get_channel_by_gport) ? (g_dkit_chip_api[lchip]->dkits_get_channel_by_gport(lchip, gport)) : (_ctc_usw_dkit_monitor_get_channel_by_gport(lchip, gport)));
        if (channel != 0xFFFFFFFF)
        {
            cmd = DRV_IOR(DsIrmPortCnt_t, DsIrmPortCnt_portCnt_f);
            index = channel;
            DRV_FIELD_IOCTL(lchip, index, cmd, &depth);

            cmd = DRV_IOR(DsIrmPortCfg_t, DsIrmPortCfg_portLimitedThrdProfId_f);
            DRV_FIELD_IOCTL(lchip, index, cmd, &profId);

            cmd = DRV_IOR(DsIrmPortLimitedThrdProfile_t, DsIrmPortLimitedThrdProfile_g_0_portLimitedThrd_f);
            DRV_FROM_TMM(lchip) ?  (DRV_FIELD_IOCTL(lchip, index, cmd, &port_thrd)) : (DRV_FIELD_IOCTL(lchip, (((profId&0xf) << 2) + congest_level), cmd, &port_thrd));

            CTC_DKITS_PRINT_FILE(p_wf, "\n--------------------------------------\n");
            CTC_DKITS_PRINT_FILE(p_wf, "%-10s%-10s%-10s%-10s\n", "Port", "Channel", "Depth", "Thrd");
            CTC_DKITS_PRINT_FILE(p_wf, "--------------------------------------\n");
            CTC_DKITS_PRINT_FILE(p_wf, "0x%04x    %-10d%-10d%-10d\n", gport, channel, depth, (port_thrd<<3));

            _ctc_usw_dkit_monitor_q_depth_igr_detail_port_tc(lchip, channel, p_wf);

        }
        else
        {
            CTC_DKITS_PRINT_FILE(p_wf, "Invalid Gport:0x%x!!!\n", gport);
        }
    }

    return CLI_SUCCESS;
}

STATIC int32
_ctc_usw_dkit_monitor_q_depth_igr(uint8 lchip, uint16 gport, sal_file_t p_wf)
{
    uint32 cmd = 0;
    uint32 resrc_mgr_en = 0;
    cmd = DRV_IOR(IrmMiscCtl_t, IrmMiscCtl_resourceCheckEn_f);
    DRV_FIELD_IOCTL(lchip, 0, cmd, &resrc_mgr_en);
    if (!resrc_mgr_en)
    {
        CTC_DKITS_PRINT_FILE(p_wf, "Ingress Resouce Mamager is Disable!!!\n");
        return CLI_SUCCESS;
    }

    if (0xFFFF == gport)
    {
        _ctc_usw_dkit_monitor_q_depth_igr_summary(lchip, p_wf);
    }
    _ctc_usw_dkit_monitor_q_depth_igr_detail(lchip, gport, p_wf);

    return CLI_SUCCESS;
}

STATIC int32
_ctc_usw_dkit_monitor_q_depth_egr_summary(uint8 lchip, sal_file_t p_wf)
{
    uint32 cmd = 0;
    uint8 i = 0, j = 0;
    uint32 value = 0;
    uint8 congest_level = 0;
    char desc[16] = {0};
    uint32 totalCnt = 0;
    uint32 egr_total_thrd = 0;
    uint32 c2c_packet_cnt = 0;
    uint32 critical_packet_cnt = 0;
    uint32 c2c_packet_thrd = 0;
    uint32 critical_packet_thrd = 0;
    uint32 sc_packet_cnt = 0;
    uint32 sc_packet_thrd = 0;
    DsErmMiscCnt_m erm_misc_cnt;
    DsErmMiscThrd_m erm_misc_thrd;

    sal_memset(&erm_misc_cnt, 0, sizeof(DsErmMiscCnt_m));
    cmd = DRV_IOR(DsErmMiscCnt_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &erm_misc_cnt);
    GetDsErmMiscCnt(A, c2cCnt_f, &erm_misc_cnt, &c2c_packet_cnt);
    GetDsErmMiscCnt(A, criticalCnt_f, &erm_misc_cnt, &critical_packet_cnt);
    GetDsErmMiscCnt(A, totalCnt_f, &erm_misc_cnt, &totalCnt);

    sal_memset(&erm_misc_thrd, 0, sizeof(DsErmMiscThrd_m));
    cmd = DRV_IOR(DsErmMiscThrd_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &erm_misc_thrd);
    GetDsErmMiscThrd(A, c2cThrd_f, &erm_misc_thrd, &c2c_packet_thrd);
    GetDsErmMiscThrd(A, criticalThrd_f, &erm_misc_thrd, &critical_packet_thrd);
    GetDsErmMiscThrd(A, totalThrd_f, &erm_misc_thrd, &egr_total_thrd);

    if (DRV_FROM_TMM(lchip))
    {
        CTC_DKITS_PRINT_FILE(p_wf, "\n-----------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10s %-10s\n", "Type", "Depth", "Drop-Thrd");
        CTC_DKITS_PRINT_FILE(p_wf, "-----------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", "Total", totalCnt, egr_total_thrd);
        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", "Critical", critical_packet_cnt, critical_packet_thrd);
        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", "C2C", c2c_packet_cnt, c2c_packet_thrd);
        j = DsErmScThrd_g_1_scThrd_f - DsErmScThrd_g_0_scThrd_f;
        for (i = 0; i < CTC_DKIT_MONITOR_SC_NUM; i++)
        {
            cmd = DRV_IOR(DsErmScThrd_t, DsErmScThrd_g_0_scThrd_f + (j*i));
            DRV_FIELD_IOCTL(lchip, 0, cmd, &sc_packet_thrd);
            cmd = DRV_IOR(DsErmScCnt_t, DsErmScCnt_g_0_scCnt_f + i);
            DRV_FIELD_IOCTL(lchip, 0, cmd, &sc_packet_cnt);
            sal_sprintf(desc, "%s%d", "SC", i);
            CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", desc, sc_packet_cnt, sc_packet_thrd<<3);
        }
    }
    else
    {
        for (j = 0; j <= 3; j++)
        {
            congest_level = _ctc_usw_dkit_monitor_get_congest_level(lchip, FALSE, j);
            CTC_DKITS_PRINT_FILE(p_wf, "\n-------SC%d congest config---------\n", j);
            CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10s\n", "level", "Thrd");
            CTC_DKITS_PRINT_FILE(p_wf, "-----------------------------------\n");
            for (i = 0; i < CTC_DKIT_MONITOR_CONGEST_LEVEL_NUM; i++)
            {
                cmd = DRV_IOR(DsErmScCngThrdProfile_t, DsErmScCngThrdProfile_g_0_scCngThrd_f + i);
                DRV_FIELD_IOCTL(lchip, j, cmd, &value);
                if (i == congest_level)
                {
                    sal_sprintf(desc, "%d%s", i, " (*)");
                }
                else
                {
                    sal_sprintf(desc, "%d", i);
                }
                CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d\n", desc, value << 5);
            }
        }

        CTC_DKITS_PRINT_FILE(p_wf, "\n-----------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10s %-10s\n", "Type", "Depth", "Drop-Thrd");
        CTC_DKITS_PRINT_FILE(p_wf, "-----------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", "Total", totalCnt, egr_total_thrd);

        if ((totalCnt >= (critical_packet_cnt + c2c_packet_cnt))
            && (egr_total_thrd >= (critical_packet_thrd + c2c_packet_thrd)))
        {
            CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", "Normal",
                                 (totalCnt - critical_packet_cnt - c2c_packet_cnt),
                                 egr_total_thrd - critical_packet_thrd - c2c_packet_thrd);
        }

        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", "Critical", critical_packet_cnt, critical_packet_thrd);
        CTC_DKITS_PRINT_FILE(p_wf, "%-14s %-10d %-10d\n", "C2C", c2c_packet_cnt, c2c_packet_thrd);
    }
    return CLI_SUCCESS;
}

STATIC int32
_ctc_usw_dkit_monitor_q_depth_egr_detail_queue(uint8 lchip, uint16 channel, sal_file_t p_wf)
{
    uint32 cmd = 0;
    uint32 chan_id = 0;
    uint32 depth = 0;
    uint32 i = 0;
    uint32 sc = 0;
    uint32 q_id = 0;
    uint32 profId = 0;
    uint8  congest_level = 0;
    uint32 queue_thrd = 0;
    uint32 field_val = 0;

    for (i = 0; i < CTC_DKIT_MONITOR_MAX_QUEUE_NUM; i++)
    {
        chan_id = ((g_dkit_chip_api[lchip]->dkits_get_channel_by_queue) ? (g_dkit_chip_api[lchip]->dkits_get_channel_by_queue(lchip, i)) : (_ctc_usw_dkit_monitor_get_channel_by_queue_id(lchip, i)));
        if (chan_id == channel)
        {
            CTC_DKITS_PRINT_FILE(p_wf, "\n-----------------------------------------------\n");
            CTC_DKITS_PRINT_FILE(p_wf, "%-10s%-10s%-10s\n", "Q-Id", "Depth", "Queue-Drop-Thrd");
            CTC_DKITS_PRINT_FILE(p_wf, "------------------------------------------------\n");

            q_id = i;
            cmd = DRV_IOR(DsErmQueueCnt_t, DsErmQueueCnt_queueCnt_f);
            DRV_FIELD_IOCTL(lchip, q_id, cmd, &depth);

            cmd = DRV_IOR(DsErmQueueCfg_t, DsErmQueueCfg_queueLimitedThrdProfId_f);
            DRV_FIELD_IOCTL(lchip, q_id, cmd, &profId);

            cmd = DRV_IOR(DsErmChannel_t, DsErmChannel_ermProfId_f);
            DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_val);

            cmd = DRV_IOR(DsErmPrioScTcMap_t, DsErmPrioScTcMap_g1_0_mappedSc_f + field_val);
            DRV_FIELD_IOCTL(lchip, i % 16, cmd, &sc);
            congest_level = DRV_FROM_TMM(lchip) ?  0 : (_ctc_usw_dkit_monitor_get_congest_level(lchip, FALSE, sc));
            cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DsErmQueueLimitedThrdProfile_g_0_queueLimitedThrd_f);
             DRV_FROM_TMM(lchip) ?  (DRV_FIELD_IOCTL(lchip, q_id, cmd, &queue_thrd)) : (DRV_FIELD_IOCTL(lchip, (((profId&0xF) << 2) + congest_level), cmd, &queue_thrd));
            CTC_DKITS_PRINT_FILE(p_wf, "%-10d%-10d%-10d\n", q_id, depth, (queue_thrd << 3));
        }
    }

    return CLI_SUCCESS;
}

STATIC int32
_ctc_usw_dkit_monitor_q_depth_egr_detail(uint8 lchip, uint16 gport, sal_file_t p_wf)
{
    uint32 cmd = 0;
    uint32 channel = 0;
    uint32 depth = 0;
    uint32 local_phy_port = 0;
    uint32 gchip = 0;
    uint32 i = 0;
    uint8 congest_level = 0;
    uint32 port_thrd = 0;
    uint32 profId = 0;
    bool b_all_zero = TRUE;

    congest_level = DRV_FROM_TMM(lchip) ?  0 : (_ctc_usw_dkit_monitor_get_congest_level(lchip, FALSE, 0));
    if (0xFFFF == gport)
    {
        CTC_DKITS_PRINT_FILE(p_wf, "\n--------------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_wf, "%-10s%-10s%-10s%-10s\n",
                       "Port", "Channel", "Depth", "Thrd");
        CTC_DKITS_PRINT_FILE(p_wf, "--------------------------------------\n");
        for (i = 0; i < CTC_DKIT_ONE_SLICE_CHANNEL_NUM; i++)
        {
            cmd = DRV_IOR(DsErmPortCnt_t, DsErmPortCnt_portCnt_f);
            DRV_FIELD_IOCTL(lchip, i , cmd, &depth);
            if (depth)
            {
                cmd = DRV_IOR(EpeHeaderAdjustPhyPortMap_t, EpeHeaderAdjustPhyPortMap_localPhyPort_f);
                DRV_FIELD_IOCTL(lchip, CTC_DKITS_CHANNEL_ENCODE(i), cmd, &local_phy_port);
                CTC_DKIT_GET_GCHIP(lchip, gchip);

                cmd = DRV_IOR(DsErmPortCfg_t, DsErmPortCfg_portLimitedThrdProfId_f);
                DRV_FIELD_IOCTL(lchip, i, cmd, &profId);

                cmd = DRV_IOR(DsErmPortLimitedThrdProfile_t, DsErmPortLimitedThrdProfile_g_0_portLimitedThrd_f);
                DRV_FROM_TMM(lchip) ?  (DRV_FIELD_IOCTL(lchip, i, cmd, &port_thrd)) : (DRV_FIELD_IOCTL(lchip, (((profId&0xf) << 2) + congest_level), cmd, &port_thrd)) ;

                CTC_DKITS_PRINT_FILE(p_wf, "0x%04x    %-10d%-10d%-10d\n",
                               CTC_DKIT_DRV_LPORT_TO_CTC_GPORT(gchip, local_phy_port),
                               i, depth, (port_thrd<<3));
                b_all_zero = FALSE;
            }
        }
        if (b_all_zero)
        {
            CTC_DKITS_PRINT_FILE(p_wf, "All port depth is zero!!!\n");
        }
        CTC_DKITS_PRINT_FILE(p_wf, "--------------------------------------\n");
    }
    else
    {
        channel = ((g_dkit_chip_api[lchip]->dkits_get_channel_by_gport) ? (g_dkit_chip_api[lchip]->dkits_get_channel_by_gport(lchip, gport)) : (_ctc_usw_dkit_monitor_get_channel_by_gport(lchip, gport)));
        if (channel != 0xFFFFFFFF)
        {
            cmd = DRV_IOR(DsErmPortCnt_t, DsErmPortCnt_portCnt_f);
            DRV_FIELD_IOCTL(lchip, channel, cmd, &depth);

            cmd = DRV_IOR(DsErmPortCfg_t, DsErmPortCfg_portLimitedThrdProfId_f);
            DRV_FIELD_IOCTL(lchip, channel, cmd, &profId);

            cmd = DRV_IOR(DsErmPortLimitedThrdProfile_t, DsErmPortLimitedThrdProfile_g_0_portLimitedThrd_f);
            DRV_FROM_TMM(lchip) ?  (DRV_FIELD_IOCTL(lchip, channel, cmd, &port_thrd)) : (DRV_FIELD_IOCTL(lchip, (((profId&0xf) << 2) + congest_level), cmd, &port_thrd));

            CTC_DKITS_PRINT_FILE(p_wf, "\n--------------------------------------\n");
            CTC_DKITS_PRINT_FILE(p_wf, "%-10s%-10s%-10s%-10s\n", "Port", "Channel", "Depth", "Thrd");
            CTC_DKITS_PRINT_FILE(p_wf, "--------------------------------------\n");
            CTC_DKITS_PRINT_FILE(p_wf, "0x%04x    %-10d%-10d%-10d\n", gport, channel, depth, (port_thrd<<3));

            _ctc_usw_dkit_monitor_q_depth_egr_detail_queue(lchip, channel, p_wf);
        }
        else
        {
            CTC_DKITS_PRINT_FILE(p_wf, "Invalid Gport:0x%x!!!\n", gport);
        }
    }

    return CLI_SUCCESS;
}

STATIC int32
_ctc_usw_dkit_monitor_q_depth_egr(uint8 lchip, uint16 gport, sal_file_t p_wf)
{
    uint32 cmd = 0;
    uint32 egr_resrc_mgr_en = 0;

    cmd = DRV_IOR(ErmMiscCtl_t, ErmMiscCtl_resourceCheckEn_f);
    DRV_FIELD_IOCTL(lchip, 0, cmd, &egr_resrc_mgr_en);
    if (0 == egr_resrc_mgr_en)
    {
        CTC_DKITS_PRINT_FILE(p_wf, "Egress Resouce Mamager is Disable!!!\n");
        return CLI_SUCCESS;
    }

    if (0xFFFF == gport)
    {
        _ctc_usw_dkit_monitor_q_depth_egr_summary(lchip, p_wf);
    }
    _ctc_usw_dkit_monitor_q_depth_egr_detail(lchip, gport, p_wf);

    return CLI_SUCCESS;
}


int32
ctc_usw_dkit_monitor_show_queue_depth(void* p_para)
{
    uint32 entry_num = 0;
    uint32 cmd = 0;
    uint32 idx = 0;
    uint32 value = 0;
    uint16 chanid = 0;
    uint16 chanid_per_dp = 0;
    uint16 gport  = 0;
    uint16 lport  = 0;
    uint8 gchip = 0;
    uint8 lchip = 0;
    bool b_all_zero = TRUE;
    ctc_dkit_monitor_para_t* p_monitor_para = (ctc_dkit_monitor_para_t*)p_para;
    sal_file_t p_wf = p_monitor_para->p_wf;
    IpeHeaderAdjustPhyPortMap_m port_map;

    DKITS_PTR_VALID_CHECK(p_para);
    lchip = p_monitor_para->lchip;
    CTC_DKIT_LCHIP_CHECK(lchip);
    DRV_INIT_CHECK(lchip);

    if (CTC_DKIT_INGRESS == p_monitor_para->dir)
    {
        if (DRV_FROM_AT(lchip))
        {
            g_dkit_chip_api[lchip]->dkits_get_q_depth_igr(lchip, p_monitor_para->gport, p_wf);
            return CLI_SUCCESS;
        }
        _ctc_usw_dkit_monitor_q_depth_igr(lchip, p_monitor_para->gport, p_wf);
    }
    else if(CTC_DKIT_EGRESS == p_monitor_para->dir)
    {
        if (DRV_FROM_AT(lchip))
        {
            g_dkit_chip_api[lchip]->dkits_get_q_depth_egr(lchip, p_monitor_para->gport, p_wf);
            return CLI_SUCCESS;
        }
        _ctc_usw_dkit_monitor_q_depth_egr(lchip, p_monitor_para->gport, p_wf);
    }
    else
    {
        if (DRV_FROM_AT(lchip))
        {
            g_dkit_chip_api[lchip]->dkits_show_q_depth(lchip, p_wf);
            return CLI_SUCCESS;
        }
        CTC_DKITS_PRINT_FILE(p_wf, "%-10s %-10s %-10s\n", "Port", "QueueID", "Depth");
        CTC_DKITS_PRINT_FILE(p_wf, "---------------------------------------------\n");

        entry_num = DRV_TABLE_MAX_INDEX(lchip, DsErmQueueCnt_t);
        for (idx = 0; idx < entry_num; idx++)
        {
            cmd = DRV_IOR(DsErmQueueCnt_t, DsErmQueueCnt_queueCnt_f);
            DRV_FIELD_IOCTL(lchip, idx, cmd, &value);
            if (0 != value)
            {
                CTC_DKIT_GET_GCHIP(lchip, gchip);
                if (g_dkit_chip_api[lchip]->dkits_get_channel_by_queue)
                {
                    chanid = g_dkit_chip_api[lchip]->dkits_get_channel_by_queue(lchip, idx);
                    chanid_per_dp = chanid < CTC_DKIT_MONITOR_CHAN_NUM_PER_DP ? chanid : (chanid % CTC_DKIT_MONITOR_CHAN_NUM_PER_DP);
                }
                else 
                {
                    chanid = _ctc_usw_dkit_monitor_get_channel_by_queue_id(lchip, idx);
                }
                if (chanid < CTC_DKIT_MONITOR_NETWORK_CHANNEL_NUM || (DRV_FROM_TMM(lchip) && chanid_per_dp < CTC_DKIT_MONITOR_NETWORK_CHANNEL_NUM_PER_DP))
                {
                    cmd = DRV_IOR(IpeHeaderAdjustPhyPortMap_t, DRV_ENTRY_FLAG);
                    DRV_IOCTL(lchip, chanid, cmd, &port_map);
                    lport = GetIpeHeaderAdjustPhyPortMap(V, localPhyPort_f, &port_map);
                    gport = CTC_DKIT_DRV_LPORT_TO_CTC_GPORT(gchip, lport);
                    CTC_DKITS_PRINT_FILE(p_wf, "0x%04x     %-10d %-10d\n", gport, idx, value);
                }
                else
                {
                    CTC_DKITS_PRINT_FILE(p_wf, "%-10s %-10d %-10d\n", "-", idx, value);
                }
                b_all_zero = FALSE;
            }
        }
        if (b_all_zero)
        {
            CTC_DKITS_PRINT_FILE(p_wf, "All Queue depth is zero!!!\n");
        }
        CTC_DKITS_PRINT_FILE(p_wf, "---------------------------------------------\n");
    }

    return CLI_SUCCESS;
}

STATIC int32
_ctc_usw_dkit_monitor_show_sensor_temperature(uint8 lchip)
{
    uint32 temp_value = 0;
    int32 ret = 0;

    if (g_dkit_chip_api[lchip]->dkits_monitor_sensor)
    {
        ret = g_dkit_chip_api[lchip]->dkits_monitor_sensor(lchip, CTC_DKIT_MONITOR_SENSOR_TEMP, &temp_value);
    }
    if (ret)
    {
        CTC_DKIT_PRINT("Read temperature fail!!!\n");
        return CLI_ERROR;
    }
    CTC_DKIT_PRINT("Temperature is %d C\n", temp_value);

    return CLI_SUCCESS;
}


STATIC int32
_ctc_usw_dkit_monitor_show_sensor_voltage(ctc_dkit_monitor_para_t* p_para)
{
    ctc_dkit_monitor_para_t* p_monitor_para = (ctc_dkit_monitor_para_t*)p_para;
    uint32 vol_value[CTC_DKITS_SENSOR_MAX_VOL_CNT] = {0};
    uint32 count = 0;
    uint32 loop = 0;
    uint8 lchip = p_monitor_para->lchip;
    int32 ret = 0;

    if (g_dkit_chip_api[lchip]->dkits_monitor_sensor)
    {
        vol_value[0] = 0;
        ret = g_dkit_chip_api[lchip]->dkits_monitor_sensor(lchip, CTC_DKIT_MONITOR_SENSOR_VOL, vol_value);
    }
    if (ret)
    {
        CTC_DKIT_PRINT("Read voltage fail!!!\n");
        return CLI_ERROR;
    }

    if (DRV_IS_TMM(lchip))
    {
        CTC_DKIT_PRINT("Serdes Ref 1024mv Voltage:\n");
        count = CTC_DKITS_SENSOR_MAX_VOL_CNT;
        for (loop = 0; loop< count; loop++)
        {
            CTC_DKIT_PRINT("    Voltage[%d] is %d mV\n",loop,vol_value[loop]);
        }

        if (g_dkit_chip_api[lchip]->dkits_monitor_sensor)
        {
            vol_value[0] = 1;
            ret = g_dkit_chip_api[lchip]->dkits_monitor_sensor(lchip, CTC_DKIT_MONITOR_SENSOR_VOL, vol_value);
        }
        if (ret)
        {
            CTC_DKIT_PRINT("Read voltage fail!!!\n");
            return CLI_ERROR;
        }
        CTC_DKIT_PRINT("Serdes Ref 1232mv Voltage:\n");
        count = CTC_DKITS_SENSOR_MAX_VOL_CNT;
        for (loop = 0; loop< count; loop++)
        {
            CTC_DKIT_PRINT("    Voltage[%d] is %d mV\n",loop,vol_value[loop]);
        }
    }
    else
    {
        CTC_DKIT_PRINT("Voltage is %d mV\n",vol_value[0]);
    }
    return CLI_SUCCESS;
}

STATIC void
_ctc_usw_dkit_monitor_temperature_handler(void* arg)
{
    int32 ret = 0;
    sal_time_t tv;
    char* p_time_str = NULL;
    sal_file_t p_file = NULL;
    uint32 temperature = 0;
    ctc_dkit_monitor_para_t* para = (ctc_dkit_monitor_para_t*)arg;
    uint8 lchip = para->lchip;

    if (para->log)
    {
        p_file = sal_fopen(para->str, "wt");
        if (!p_file)
        {
            CTC_DKIT_PRINT("Open file %s fail!!!\n", para->str);
            return;
        }
        sal_fclose(p_file);
        p_file = NULL;
    }

    while (1)
    {
        if (para->log && (NULL == p_file))
        {
            p_file = sal_fopen(para->str, "a");
        }
        /*get systime*/
        sal_time(&tv);
        p_time_str = sal_ctime(&tv);
        if (g_dkit_chip_api[lchip]->dkits_monitor_sensor)
        {
            ret = g_dkit_chip_api[lchip]->dkits_monitor_sensor(lchip, CTC_DKIT_MONITOR_SENSOR_TEMP, &temperature);
        }
        if (ret)
        {
            CTC_DKITS_PRINT_FILE(p_file, "Read temperature fail!!\n");
        }
        else if (para->enable && !(temperature & 0x80000000) && temperature >= para->temperature)
        {
            CTC_DKITS_PRINT_FILE(p_file, "t = %-4d, %s", temperature, p_time_str);
        }

        if (para->enable && !(temperature & 0x80000000) && temperature >= para->power_off_temp) /*reboot*/
        {
            CTC_DKITS_PRINT_FILE(p_file, "system reboot!!!\n");
            if (p_file)
            {
                sal_fclose(p_file);
            }
#if defined SDK_IN_USERMODE
            reboot(RB_AUTOBOOT);
#endif
            return;
        }
        sal_task_sleep(para->interval*1000);

        if(0 == para->enable)
        {
            goto END;
        }
    }

END:
    if (p_file)
    {
        sal_fclose(p_file);
    }
    return;
}

STATIC int32
_ctc_usw_dkit_monitor_temperature(void* p_para)
{
    int32 ret = CLI_SUCCESS;
    uint8 lchip = 0;
    uint8 task_id = CTC_DKIT_MONITOR_TASK_TEMPERATURE;
    ctc_dkit_monitor_para_t* p_monitor_para = (ctc_dkit_monitor_para_t*)p_para;
    char buffer[SAL_TASK_MAX_NAME_LEN] = {0};

    DKITS_PTR_VALID_CHECK(p_monitor_para);
    lchip = p_monitor_para->lchip;
    CTC_DKIT_LCHIP_CHECK(lchip);
    DKITS_PTR_VALID_CHECK(g_usw_dkit_master[lchip]);

#if (SDK_WORK_PLATFORM==1)
    return ret;
#endif
    
#if (MCHIP_SIM == 1)
    if (dal_chip_is_sim(DRV_MAP_LDEV(lchip)))
    {
        return ret;
    }
#endif

    if ((p_monitor_para->enable) && (NULL == g_usw_dkit_master[lchip]->monitor_task[task_id].monitor_task))
    {
        if (NULL == g_usw_dkit_master[lchip]->monitor_task[task_id].para)
        {
            g_usw_dkit_master[lchip]->monitor_task[task_id].para
                   = (ctc_dkit_monitor_para_t*)mem_malloc(MEM_CLI_MODULE, sizeof(ctc_dkit_monitor_para_t));
            if (NULL == g_usw_dkit_master[lchip]->monitor_task[task_id].para)
            {
                return CLI_ERROR;
            }
        }
        sal_memcpy(g_usw_dkit_master[lchip]->monitor_task[task_id].para, p_para , sizeof(ctc_dkit_monitor_para_t));

        sal_sprintf(buffer, "Temperature-%d", lchip);
        ret = sal_task_create(&g_usw_dkit_master[lchip]->monitor_task[task_id].monitor_task,
                                                  buffer,
                                                  SAL_DEF_TASK_STACK_SIZE,
                                                  SAL_TASK_PRIO_DEF,
                                                  _ctc_usw_dkit_monitor_temperature_handler,
                                                  g_usw_dkit_master[lchip]->monitor_task[task_id].para);

        if (0 != ret)
        {
            CTC_DKIT_PRINT("Temperature monitor task create fail!\n");
            return CLI_ERROR;
        }
    }
    else if(0 == p_monitor_para->enable)
    {
        if (g_usw_dkit_master[lchip]->monitor_task[task_id].monitor_task)
        {
            sal_task_destroy(g_usw_dkit_master[lchip]->monitor_task[task_id].monitor_task);
            g_usw_dkit_master[lchip]->monitor_task[task_id].monitor_task = NULL;
        }
        if (g_usw_dkit_master[lchip]->monitor_task[task_id].para)
        {
            sal_memset(g_usw_dkit_master[lchip]->monitor_task[task_id].para, 0 ,sizeof(ctc_dkit_monitor_para_t));
        }
    }

    return CLI_SUCCESS;
}

STATIC void
_ctc_usw_dkit_monitor_buffer_handler(void* arg)
{
    sal_systime_t tv;
    sal_file_t p_file = NULL;
    ctc_dkit_monitor_para_t* para = (ctc_dkit_monitor_para_t*)arg;
    uint8 lchip = para->lchip;

    if (!DRV_FROM_AT(lchip))
    {
        return;
    }

    if (para->log)
    {
        p_file = sal_fopen(para->str, "wt");
        if (!p_file)
        {
            CTC_DKIT_PRINT("Open file %s fail!!!\n", para->str);
            return;
        }
        sal_fclose(p_file);
        p_file = NULL;
    }

    while (1)
    {
        uint32 cmd = 0;
        uint8 cnt[64] = {0};
        uint8 max = 0;
        uint8 min = 255;
        uint8 i = 0;
        uint8 j = 0;
        BufStoreUcFreePtrCntCapCtl_m uc_ctl;
        BufStoreMcFreePtrCntCapCtl_m mc_ctl;
        BufStoreUcFreePtrSnapShot_m uc_snap;
        BufStoreMcFreePtrSnapShot_m mc_snap;

        sal_memset(&uc_ctl, 0, sizeof(uc_ctl));
        sal_memset(&mc_ctl, 0, sizeof(mc_ctl));

        if (para->log && (NULL == p_file))
        {
            p_file = sal_fopen(para->str, "a");
        }

        /*get systime*/
        ctc_sal_gettime(&tv);

        CTC_DKITS_PRINT_FILE(p_file,"[%-10u:%-6u]",tv.tv_sec, tv.tv_usec);
        CTC_DKITS_PRINT_FILE(p_file,"%s\n%s", (para->is_mc ? "[MC]" : "[UC]"),
                                            (para->detail ? "[ID total used left]\n" : ""));

        if (!para->is_mc)
        {
            cmd = DRV_IOW(BufStoreUcFreePtrCntCapCtl_t, DRV_ENTRY_FLAG);
            SetBufStoreUcFreePtrCntCapCtl(V, freePtrRamCntCapEn_f, &uc_ctl, 1);
            DRV_IOCTL(lchip, 0, cmd, &uc_ctl);
            for (i = 0;i < 4; i++)
            {
                cmd = DRV_IOR(BufStoreUcFreePtrSnapShot_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, cmd, &uc_snap);
                for (j = 0;j < 16; j++)
                {
                    cnt[j + 16*i] = GetBufStoreUcFreePtrSnapShot(V, freePtrRam_0_captureCnt_f + j, &uc_snap);
                    max = cnt[j + 16*i] > max ? cnt[j + 16*i] : max;
                    min = cnt[j + 16*i] < min ? cnt[j + 16*i] : min;
                    if (para->detail)
                    {
                        CTC_DKITS_PRINT_FILE(p_file, " %-3d%-6u%-5u%-4u\n", (j + 16*i),
                                        CTC_DKIT_MONITOR_UC_QUEUE_ENTRY_MEM_PRE_RAM,
                                        (CTC_DKIT_MONITOR_UC_QUEUE_ENTRY_MEM_PRE_RAM - cnt[j + 16*i]),
                                        cnt[j + 16*i]);
                    }
                }
            }
        }
        else
        {
            cmd = DRV_IOW(BufStoreMcFreePtrCntCapCtl_t, DRV_ENTRY_FLAG);
            SetBufStoreMcFreePtrCntCapCtl(V, freePtrRamCntCapEn_f, &mc_ctl, 1);
            DRV_IOCTL(lchip, 0, cmd, &mc_ctl);
            cmd = DRV_IOR(BufStoreMcFreePtrSnapShot_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, cmd, &mc_snap);
            for (i = 0;i < 64; i++)
            {
                cnt[i] = GetBufStoreMcFreePtrSnapShot(V, freePtrRam_0_captureCnt_f + i, &mc_snap);
                max = cnt[i] > max ? cnt[i] : max;
                min = cnt[i] < min ? cnt[i] : min;
                if (para->detail)
                {
                    CTC_DKITS_PRINT_FILE(p_file, " %-3d%-6u%-5u%-4u\n", i,
                                        CTC_DKIT_MONITOR_MC_QUEUE_ENTRY_MEM_PRE_RAM,
                                        (CTC_DKIT_MONITOR_MC_QUEUE_ENTRY_MEM_PRE_RAM - cnt[i]),
                                        cnt[i]);
                }
            }
        }
        if(max - min >= para->thrd)
        {
            CTC_DKITS_PRINT_FILE(p_file, "count exceed thrd! max = %d, min = %d", max, min);
        }
        CTC_DKITS_PRINT_FILE(p_file, "MAX:%d\n", max);
        CTC_DKITS_PRINT_FILE(p_file, "MIN:%d\n", min);
        CTC_DKITS_PRINT_FILE(p_file, "Delta:%d\n", (max - min));
        CTC_DKITS_PRINT_FILE(p_file, "\n");
        sal_task_sleep(para->interval);

        if(0 == para->enable)
        {
            goto END;
        }
    }

END:
    if (p_file)
    {
        sal_fclose(p_file);
    }
    return;
}

STATIC void
_ctc_usw_dkit_monitor_queue_entry_handler(void* arg)
{
    sal_systime_t tv;
    sal_file_t p_file = NULL;
    ctc_dkit_monitor_para_t* para = (ctc_dkit_monitor_para_t*)arg;
    uint8 lchip = para->lchip;
    uint32 count0 = 0;
    uint32 count1 = 0;
    uint32 count2 = 0;
    uint32 min = 0;
    uint32 max = 0;
    uint8 i = 0;
    uint8 j = 0;
    uint8 is_mc = 0;
    uint8 max_rec[2] = {0};
    uint8 min_rec[2] = {255, 255};
    uint8 delta[2] = {0,0};
	uint32 cnt_diff_tmp = 0;
	uint32 cnt_diff = 0;

    if (para->log)
    {
        p_file = sal_fopen(para->str, "wt");
        if (!p_file)
        {
            CTC_DKIT_PRINT("Open file %s fail!!!\n", para->str);
            return;
        }
        sal_fclose(p_file);
        p_file = NULL;
    }

    while (1)
    {
        if (para->log && (NULL == p_file))
        {
            p_file = sal_fopen(para->str, "a");
        }
        /*get systime*/
        sal_gettime(&tv);
        if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
#if (0 == SDK_WORK_PLATFORM)
            uint32 cmd = 0;

            QMgrFreePtrCtl_m free_ptr;
            QMgrFreePtrInfo_m free_ptr_info;

            cmd = DRV_IOR(QMgrFreePtrCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, cmd, &free_ptr);
            count0 = GetQMgrFreePtrCtl(V, gFreeCtl_0_count_f, &free_ptr);
            count1 = GetQMgrFreePtrCtl(V, gFreeCtl_1_count_f, &free_ptr);
            count2 = GetQMgrFreePtrCtl(V, gFreeCtl_2_count_f, &free_ptr);

            cmd = DRV_IOR(QMgrFreePtrInfo_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, cmd, &free_ptr_info);
            cnt_diff_tmp = GetQMgrFreePtrInfo(V, maxFreeCntDiff_f, &free_ptr_info);
#endif
            // output to file
            CTC_DKITS_PRINT_FILE(p_file, "[%-10u:%-6u] [ramid:total:used:left] ram0:%-5u:%-5u:%-5u, ram1:%-5u:%-5u:%-5u, ram2:%-5u:%-5u:%-5u, max_idff = %d", tv.tv_sec, tv.tv_usec,
                        CTC_DKIT_MONITOR_QUEUE_ENTRY_MEM_PRE_RAM, CTC_DKIT_MONITOR_QUEUE_ENTRY_MEM_PRE_RAM-count0, count0,
                        CTC_DKIT_MONITOR_QUEUE_ENTRY_MEM_PRE_RAM, CTC_DKIT_MONITOR_QUEUE_ENTRY_MEM_PRE_RAM-count1, count1,
                        CTC_DKIT_MONITOR_QUEUE_ENTRY_MEM_PRE_RAM, CTC_DKIT_MONITOR_QUEUE_ENTRY_MEM_PRE_RAM-count2, count2,
                        cnt_diff_tmp);
            max = count0 > count1 ? (count0 > count2 ? count0 : count2) : (count1 > count2 ? count1 : count2);
            min = count0 > count1 ? (count1 > count2 ? count2 : count1) : (count0 > count2 ? count2 : count0);
            if(max - min >= para->thrd)
            {
                CTC_DKITS_PRINT_FILE(p_file, "count exceed thrd! max = %d, min = %d", max, min);
            }
            CTC_DKITS_PRINT_FILE(p_file, "\n");

            // output to console
            if(max - min >= para->thrd || cnt_diff_tmp != cnt_diff)
            {
                cnt_diff = cnt_diff_tmp;
                CTC_DKITS_PRINT_FILE(p_file, "[%-10u:%-6u] [ramid:total:used:left] ram0:%-5u:%-5u:%-5u, ram1:%-5u:%-5u:%-5u, ram2:%-5u:%-5u:%-5u", tv.tv_sec, tv.tv_usec,
                    CTC_DKIT_MONITOR_QUEUE_ENTRY_MEM_PRE_RAM, CTC_DKIT_MONITOR_QUEUE_ENTRY_MEM_PRE_RAM-count0, count0,
                    CTC_DKIT_MONITOR_QUEUE_ENTRY_MEM_PRE_RAM, CTC_DKIT_MONITOR_QUEUE_ENTRY_MEM_PRE_RAM-count1, count1,
                    CTC_DKIT_MONITOR_QUEUE_ENTRY_MEM_PRE_RAM, CTC_DKIT_MONITOR_QUEUE_ENTRY_MEM_PRE_RAM-count2, count2);
                CTC_DKITS_PRINT_FILE(p_file, "count exceed thrd! max = %d, min = %d, max_diff = %d", max, min, cnt_diff);
                CTC_DKITS_PRINT_FILE(p_file, "\n");
            }
        }
        else if (DRV_FROM_AT(lchip))
        {
            uint32 cmd = 0;
            uint8 cnt[64] = {0};
            uint8 max = 0;
            uint8 min = 255;
            BufStoreUcFreePtrCntCapCtl_m uc_ctl;
            BufStoreMcFreePtrCntCapCtl_m mc_ctl;
            BufStoreUcFreePtrSnapShot_m uc_snap;
            BufStoreMcFreePtrSnapShot_m mc_snap;

            for (is_mc = 0; is_mc < 2; is_mc++)
            {
                max = 0;
                min = 255;
                sal_memset(&uc_ctl, 0, sizeof(uc_ctl));
                sal_memset(&mc_ctl, 0, sizeof(mc_ctl));

                CTC_DKITS_PRINT_FILE(p_file,"\n%s [%-10u:%-6u]\n",  (is_mc ? "[MC]" : "[UC]"), tv.tv_sec, tv.tv_usec);
                if (para->detail)
                {
                    CTC_DKITS_PRINT_FILE(p_file,"%s %s\n", (is_mc ? "[MC]" : "[UC]"), "[ramid total used left]\n");
                }

                if (!is_mc)
                {
                    cmd = DRV_IOW(BufStoreUcFreePtrCntCapCtl_t, DRV_ENTRY_FLAG);
                    SetBufStoreUcFreePtrCntCapCtl(V, freePtrRamCntCapEn_f, &uc_ctl, 1);
                    DRV_IOCTL(lchip, 0, cmd, &uc_ctl);
                    for (i = 0;i < 4; i++)
                    {
                        cmd = DRV_IOR(BufStoreUcFreePtrSnapShot_t, DRV_ENTRY_FLAG);
                        DRV_IOCTL(lchip, i, cmd, &uc_snap);
                        for (j = 0;j < 16; j++)
                        {
                            cnt[j + 16*i] = GetBufStoreUcFreePtrSnapShot(V, freePtrRam_0_captureCnt_f + j, &uc_snap);
                            max = cnt[j + 16*i] > max ? cnt[j + 16*i] : max;
                            min = cnt[j + 16*i] < min ? cnt[j + 16*i] : min;
                            if (para->detail)
                            {
                                CTC_DKITS_PRINT_FILE(p_file, "%s %-6d%-6u%-5u%-4u\n", (is_mc ? "[MC]" : "[UC]"), (j + 16*i),
                                                CTC_DKIT_MONITOR_UC_QUEUE_ENTRY_MEM_PRE_RAM,
                                                (CTC_DKIT_MONITOR_UC_QUEUE_ENTRY_MEM_PRE_RAM - cnt[j + 16*i]),
                                                cnt[j + 16*i]);
                            }
                        }
                    }
                }
                else
                {
                    cmd = DRV_IOW(BufStoreMcFreePtrCntCapCtl_t, DRV_ENTRY_FLAG);
                    SetBufStoreMcFreePtrCntCapCtl(V, freePtrRamCntCapEn_f, &mc_ctl, 1);
                    DRV_IOCTL(lchip, 0, cmd, &mc_ctl);
                    cmd = DRV_IOR(BufStoreMcFreePtrSnapShot_t, DRV_ENTRY_FLAG);
                    DRV_IOCTL(lchip, 0, cmd, &mc_snap);
                    for (i = 0;i < 64; i++)
                    {
                        cnt[i] = GetBufStoreMcFreePtrSnapShot(V, freePtrRam_0_captureCnt_f + i, &mc_snap);
                        max = cnt[i] > max ? cnt[i] : max;
                        min = cnt[i] < min ? cnt[i] : min;
                        if (para->detail)
                        {
                            CTC_DKITS_PRINT_FILE(p_file, "%s %-6d%-6u%-5u%-4u\n", (is_mc ? "[MC]" : "[UC]"), i,
                                                CTC_DKIT_MONITOR_MC_QUEUE_ENTRY_MEM_PRE_RAM,
                                                (CTC_DKIT_MONITOR_MC_QUEUE_ENTRY_MEM_PRE_RAM - cnt[i]),
                                                cnt[i]);
                        }
                    }
                }
                if(max - min >= para->thrd)
                {
                    CTC_DKITS_PRINT_FILE(p_file, "%s count exceed thrd! max = %d, min = %d", (is_mc ? "[MC]" : "[UC]"), max, min);
                }
                if (delta[is_mc] < (max - min))
                {
                    delta[is_mc] = max - min;
                    max_rec[is_mc] = max;
                    min_rec[is_mc] = min;
                }
                CTC_DKITS_PRINT_FILE(p_file, "%s MAX:%d\n", (is_mc ? "[MC]" : "[UC]"), max);
                CTC_DKITS_PRINT_FILE(p_file, "%s MIN:%d\n", (is_mc ? "[MC]" : "[UC]"), min);
                CTC_DKITS_PRINT_FILE(p_file, "%s Delta:%d\n", (is_mc ? "[MC]" : "[UC]"), (max - min));
            }
        }
        CTC_DKITS_PRINT_FILE(p_file, "\n");
        sal_task_sleep(para->interval);

        if(0 == para->enable)
        {
            CTC_DKITS_PRINT_FILE(p_file, "%s MAX:%d\n", ("[UC]"), max_rec[0]);
            CTC_DKITS_PRINT_FILE(p_file, "%s MIN:%d\n", ("[UC]"), min_rec[0]);
            CTC_DKITS_PRINT_FILE(p_file, "%s Delta:%d\n", ("[UC]"), delta[0]);

            CTC_DKITS_PRINT_FILE(p_file, "%s MAX:%d\n", ("[MC]"), max_rec[1]);
            CTC_DKITS_PRINT_FILE(p_file, "%s MIN:%d\n", ("[MC]"), min_rec[1]);
            CTC_DKITS_PRINT_FILE(p_file, "%s Delta:%d\n", ("[MC]"), delta[1]);
            goto END;
        }
    }

END:
    if (p_file)
    {
        sal_fclose(p_file);
    }
    return;
}


STATIC int32
_ctc_usw_dkit_monitor_resrc(void* p_para)
{
    int32 ret = 0;
    uint8 lchip = 0;
    ctc_dkit_monitor_para_t* p_monitor_para = (ctc_dkit_monitor_para_t*)p_para;
    uint8 task_id = CTC_DKIT_MONITOR_SENSOR_BUFFER_NOMITOR == p_monitor_para->sensor_mode ? 
                    CTC_DKIT_MONITOR_TASK_BUFFER : CTC_DKIT_MONITOR_TASK_QUEUE_ENTRY;
    char buffer[SAL_TASK_MAX_NAME_LEN] = {0};

    DKITS_PTR_VALID_CHECK(p_monitor_para);
    lchip = p_monitor_para->lchip;
    CTC_DKIT_LCHIP_CHECK(lchip);
    DKITS_PTR_VALID_CHECK(g_usw_dkit_master[lchip]);

    if(!DRV_FROM_TMM(lchip))
    {
        return CLI_ERROR;
    }
    if ((p_monitor_para->enable) && (NULL == g_usw_dkit_master[lchip]->monitor_task[task_id].monitor_task))
    {
        if (NULL == g_usw_dkit_master[lchip]->monitor_task[task_id].para)
        {
            g_usw_dkit_master[lchip]->monitor_task[task_id].para
                   = (ctc_dkit_monitor_para_t*)mem_malloc(MEM_CLI_MODULE, sizeof(ctc_dkit_monitor_para_t));
            if (NULL == g_usw_dkit_master[lchip]->monitor_task[task_id].para)
            {
                return CLI_ERROR;
            }
        }
        sal_memcpy(g_usw_dkit_master[lchip]->monitor_task[task_id].para, p_para , sizeof(ctc_dkit_monitor_para_t));

        if (CTC_DKIT_MONITOR_SENSOR_BUFFER_NOMITOR == p_monitor_para->sensor_mode)
        {
            sal_sprintf(buffer, "Buffer-%d", lchip);
            ret = sal_task_create(&g_usw_dkit_master[lchip]->monitor_task[task_id].monitor_task,
                                                    buffer,
                                                    SAL_DEF_TASK_STACK_SIZE,
                                                    SAL_TASK_PRIO_DEF,
                                                    _ctc_usw_dkit_monitor_buffer_handler,
                                                    g_usw_dkit_master[lchip]->monitor_task[task_id].para);

            if (0 != ret)
            {
                CTC_DKIT_PRINT("Buffer monitor task create fail!\n");
                return CLI_ERROR;
            }
        }
        else
        {
            sal_sprintf(buffer, "Queue entry-%d", lchip);
            ret = sal_task_create(&g_usw_dkit_master[lchip]->monitor_task[task_id].monitor_task,
                                                    buffer,
                                                    SAL_DEF_TASK_STACK_SIZE,
                                                    SAL_TASK_PRIO_DEF,
                                                    _ctc_usw_dkit_monitor_queue_entry_handler,
                                                    g_usw_dkit_master[lchip]->monitor_task[task_id].para);

            if (0 != ret)
            {
                CTC_DKIT_PRINT("Queue entry monitor task create fail!\n");
                return CLI_ERROR;
            }
        }
    }
    else if(0 == p_monitor_para->enable)
    {
        if (g_usw_dkit_master[lchip]->monitor_task[task_id].para)
        {
            sal_memset(g_usw_dkit_master[lchip]->monitor_task[task_id].para, 0 ,sizeof(ctc_dkit_monitor_para_t));
        }
        if (g_usw_dkit_master[lchip]->monitor_task[task_id].monitor_task)
        {
            sal_task_destroy(g_usw_dkit_master[lchip]->monitor_task[task_id].monitor_task);
            g_usw_dkit_master[lchip]->monitor_task[task_id].monitor_task = NULL;
        }
    }

    return CLI_SUCCESS;
}

int32
ctc_usw_dkit_monitor_show_sensor_result(void* p_para)
{
    ctc_dkit_monitor_para_t* p_monitor_para = (ctc_dkit_monitor_para_t*)p_para;
    DKITS_PTR_VALID_CHECK(p_para);
    CTC_DKIT_LCHIP_CHECK(p_monitor_para->lchip);
    DRV_INIT_CHECK(p_monitor_para->lchip);

    if (CTC_DKIT_MONITOR_SENSOR_TEMP == p_monitor_para->sensor_mode)
    {
        return  _ctc_usw_dkit_monitor_show_sensor_temperature(p_monitor_para->lchip);
    }
    else if (CTC_DKIT_MONITOR_SENSOR_VOL == p_monitor_para->sensor_mode)
    {
        return  _ctc_usw_dkit_monitor_show_sensor_voltage(p_para);
    }
    else if(CTC_DKIT_MONITOR_SENSOR_TEMP_NOMITOR == p_monitor_para->sensor_mode)
    {
        return  _ctc_usw_dkit_monitor_temperature(p_para);
    }
    else if(CTC_DKIT_MONITOR_SENSOR_QENTRY_NOMITOR == p_monitor_para->sensor_mode
         || CTC_DKIT_MONITOR_SENSOR_BUFFER_NOMITOR == p_monitor_para->sensor_mode)
    {
        return  _ctc_usw_dkit_monitor_resrc(p_para);
    }
    return CLI_SUCCESS;
}


